<!DOCTYPE html><html><head>
<title>同步、异步、并发、阻塞、非阻塞、回调函数、promise、async、await.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/*

Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>

*/

.hljs {
  display: block;
  overflow-x: auto;
  padding: 0.5em;
  background: #FFFFFF;
}

.hljs,
.hljs-subst {
  color: #434f54;
}

.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-doctag,
.hljs-name {
  color: #00979D;
}

.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
  color: #D35400;
}

.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
  color: #00979D;
}

.hljs-type,
.hljs-string,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
  color: #005C5F;
}

.hljs-title,
.hljs-section {
  color: #880000;
  font-weight: bold;
}

.hljs-comment {
  color: rgba(149,165,166,.8);
}

.hljs-meta-keyword {
  color: #728E00;
}

.hljs-meta {
  color: #434f54;
}

.hljs-emphasis {
  font-style: italic;
}

.hljs-strong {
  font-weight: bold;
}

.hljs-function {
  color: #728E00;
}

.hljs-number {
  color: #8A7B52;  
}

</style>

<style>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family:   "HelveticaNeue-Light", sans-serif, "宋体","Segoe WPC", "Segoe UI", "SFUIText-Light","Droid Sans Fallback";
	font-size: 18px;
	padding: 0 12px;
	line-height: 1.6;
	word-wrap: break-word;
	color: #333333;
}

.content-wrapper{
	max-width: 860px;
    margin: 0 auto;
    padding: 0 30px;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}


body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	color: #4080D0;
	text-decoration: none;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom: 1px solid #eee;
}


h2{
	padding-bottom: .3em;
    font-size: 2em;
    line-height: 1.225;
    border-bottom: 1px solid #eee;
}

h3{
	font-size: 1.75em;
    line-height: 1.225;
}

h1, h2, h3 {
	font-weight: bold;
}

h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
	font-size: inherit;
	line-height: auto;
}

a:hover {
	color: #4080D0;
	text-decoration: underline;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left: 5px solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 14px;
	line-height: 19px;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

.mac code {
	font-size: 12px;
	line-height: 18px;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

/** Theming */

.vscode-light,
.vscode-light pre code {
	color: rgb(30, 30, 30);
}

.vscode-dark,
.vscode-dark pre code {
	color: #DDD;
}

.vscode-high-contrast,
.vscode-high-contrast pre code {
	color: white;
}

.vscode-light code {
	color: #A31515;
}

.vscode-dark code {
	color: #D7BA7D;
}

.vscode-light pre:not(.hljs),
.vscode-light code > div {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

.vscode-light blockquote,
.vscode-dark blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.vscode-high-contrast blockquote {
	background: transparent;
	border-color: #fff;
}
</style>

<style>
pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: #C9AE75; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

.table-of-contents li{
	list-style-type: initial;
}
</style>

<style>
@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.2"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}

</style>

</head>
<body>
    <div class="content-wrapper">
        <h1 id="%E5%90%8C%E6%AD%A5%E3%80%81%E5%BC%82%E6%AD%A5%E3%80%81%E5%B9%B6%E5%8F%91%E3%80%81%E9%98%BB%E5%A1%9E%E3%80%81%E9%9D%9E%E9%98%BB%E5%A1%9E%E3%80%81%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E3%80%81promise%E3%80%81async%2Fawait" tabindex="-1">同步、异步、并发、阻塞、非阻塞、回调函数、promise、async/await</h1>
<h3 id="%E4%B8%80%E3%80%81%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5%EF%BC%9F" tabindex="-1">一、同步与异步？</h3>
<h5 id="%E5%90%8C%E6%AD%A5%EF%BC%88synchronous%EF%BC%89" tabindex="-1">同步（Synchronous）</h5>
<p>同步是一种任务执行模式，其中任务按<strong>顺序执行</strong>，并且每个任务都必须等待前一个任务完成后才能开始。简单来说，<strong>同步执行</strong>意味着任务之间有严格的顺序依赖，任务一旦开始，就会阻塞其他任务，直到当前任务完成。</p>
<ul>
<li>
<p><strong>顺序性</strong>：同步任务按照固定的顺序依次执行，前一个任务完成后才会启动下一个任务。</p>
</li>
<li>
<p><strong>阻塞性</strong>：在同步模型中，每个任务都会阻塞执行，直到前一个任务完成才能开始下一个任务。</p>
<p>例如，假设有三个任务：A、B、C。在同步执行中，只有当任务 A 完成后，任务 B 才会开始执行，而任务 C 又必须等到任务 B 完成才会启动。</p>
</li>
</ul>
<h5 id="%E5%BC%82%E6%AD%A5%EF%BC%88asynchronous%EF%BC%89" tabindex="-1">异步（Asynchronous）</h5>
<p>与同步相对，异步执行则意味着任务之间的执行没有严格的顺序要求。任务可以在等待期间继续执行其他任务，无需等待前一个任务完成。换句话说，异步任务可以在不阻塞的情况下执行，允许多个任务并行进行。</p>
<ul>
<li><strong>独立执行</strong>：每个任务的执行不依赖于其他任务，可以在其他任务执行时继续进行。</li>
<li><strong>非阻塞</strong>：异步操作允许在等待某个任务的结果时，继续执行其他任务，避免了任务间的阻塞。</li>
</ul>
<p>例如，在异步模型中，当任务 A 开始执行时，任务 B 和 C 可以同时进行，而无需等待任务 A 完成。即使任务 A 需要较长时间处理，B 和 C 也可以在任务 A 执行期间完成自己的工作。</p>
<h5 id="%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5%E7%9A%84%E6%9C%AC%E8%B4%A8%E5%8C%BA%E5%88%AB" tabindex="-1">同步与异步的本质区别</h5>
<p>同步与异步的本质区别在于任务执行时是否存在等待与阻塞机制。</p>
<ul>
<li>同步：任务之间严格顺序执行，后一个任务必须等待前一个任务完成。</li>
<li>异步：任务不需要等待，可以并行执行，不会因为前一个任务未完成而阻塞后续任务的执行。</li>
</ul>
<p>这意味着，同步程序通常是<strong>阻塞式的</strong>，即每个任务完成后才进行下一个任务；而异步程序通常是<strong>非阻塞的</strong>，即使某些任务还在等待过程中，其他任务也可以继续执行。</p>
<h5 id="%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B%E4%B8%8E%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%E5%85%B3%E7%B3%BB" tabindex="-1">线程模型与任务执行关系</h5>
<ul>
<li>
<p>单线程模式：在单线程中，程序只能一次执行一个任务。在这种情况下，任务执行方式可以是同步或异步。</p>
<ul>
<li>同步单线程：任务按顺序执行，程序必须等待每个任务完成后才能继续执行下一个任务，表现为阻塞行为。</li>
<li>异步单线程：通过事件循环或回调机制，任务可以在等待外部资源时继续执行其他任务，程序不会被阻塞。像 Node.js 就采用了单线程的异步模型，通过事件循环机制处理多个并发任务。</li>
</ul>
</li>
<li>
<p>多线程模式：在多线程中，任务分布在不同的线程中，允许多个任务并行执行。多线程可以采用同步或异步的方式，具体取决于任务间的依赖关系。</p>
<ul>
<li>同步多线程：多个线程间的任务依然需要遵循同步机制，如通过锁、信号量等手段保证任务按顺序执行。</li>
<li>异步多线程：多个线程独立执行任务，各个线程之间没有依赖关系，线程的执行不需要等待其他线程完成。</li>
</ul>
</li>
</ul>
<h5 id="%E5%90%8C%E6%AD%A5%E5%92%8C%E5%BC%82%E6%AD%A5%E4%B8%8E%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%85%B3%E7%B3%BB" tabindex="-1">同步和异步与线程的关系</h5>
<p>同步和异步并不直接要求使用多线程或单线程。它们关注的是任务的等待机制，而线程模型关注的是任务在物理线程上的分配。换句话说：</p>
<ul>
<li>同步：无论是在单线程还是多线程中，任务之间存在依赖关系，后一个任务必须等待前一个任务完成。</li>
<li>异步：任务可以并行执行，即使在单线程中，也可以通过事件循环来实现异步执行，避免任务之间的等待。</li>
</ul>
<p>因此，同步和异步可以在单线程或多线程环境中实现，关键在于任务的等待机制和执行顺序，而不是线程的数量。</p>
<h5 id="%E6%AD%A3%E7%A1%AE%E7%9A%84%E7%90%86%E8%A7%A3" tabindex="-1">正确的理解</h5>
<p>同步和异步关注的是任务的 等待机制 ：</p>
<ul>
<li><strong>同步</strong>：任务必须等待前一个任务完成，可能阻塞执行。</li>
<li><strong>异步</strong>：任务不需要等待，可以在等待期间继续执行其他任务。</li>
</ul>
<p>而线程模型关注的是任务的并发执行方式：</p>
<ul>
<li><strong>单线程</strong>：任务在一个线程中执行，可以是同步或异步。</li>
<li><strong>多线程</strong>：任务分布在多个线程中，可以是同步或异步。</li>
</ul>
<p>两者的核心概念相互独立，但可以结合使用。例如：</p>
<ul>
<li><strong>单线程同步</strong>（任务按顺序执行，无并发）</li>
<li><strong>单线程异步</strong>（通过事件循环实现并发任务）</li>
<li><strong>多线程同步</strong>（多个线程按同步机制执行任务）</li>
<li><strong>多线程异步</strong>（多个线程异步处理任务，彼此独立）</li>
</ul>
<h3 id="%E4%BA%8C%E3%80%81callback%E5%9B%9E%E8%B0%83" tabindex="-1">二、callback回调</h3>
<p>回调函数是一种在编程中常见的概念，它是指一个函数作为参数传递给另一个函数，并且在<strong>特定事件发生或条件满足时被调用执行的函数</strong>。</p>
<p>回调只是使用JavaScript函数的惯例的名称。 JavaScript语言中没有特别的东西叫做“回调”，它只是一个约定。
不像大多数函数那样立即返回一些结果，使用<strong>回调函数</strong>需要一些时间来产生结果。通常回调仅在进行I / O时使用，例如下载东西，阅读文件，与数据库交互等。</p>
<p>案例：</p>
<pre class="hljs"><code><div><span class="hljs-keyword">function</span> <span class="hljs-title function_">a</span> (<span class="hljs-params">fn</span>){
        <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=&gt;</span>{
            <span class="hljs-keyword">let</span> sum = <span class="hljs-number">10</span>
            <span class="hljs-title function_">fn</span>(sum)
        },<span class="hljs-number">1000</span>)
    
    }

    <span class="hljs-title function_">a</span>(<span class="hljs-function">(<span class="hljs-params">arr</span>)=&gt;</span>{
        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr);
    })


    <span class="hljs-keyword">function</span> <span class="hljs-title function_">b</span>(<span class="hljs-params">params</span>) {
        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(params);
    }
    <span class="hljs-title function_">a</span>(b)
</div></code></pre>
<h3 id="%E4%B8%89%E3%80%81%E5%9B%9E%E8%B0%83%E5%9C%B0%E7%8B%B1" tabindex="-1">三、回调地狱</h3>
<pre class="hljs"><code><div><span class="hljs-comment">// 回调地狱，当回调函数互相嵌套，嵌套层级过多，导致代码维护性变差，这种结构就是我们常说的回调地狱</span>
<span class="hljs-comment">// 以前发送请求的时候，用的ajax的方式去请求数据。</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">ajax</span>(<span class="hljs-params">url,sucesscb,errorcb</span>){
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=&gt;</span>{
        <span class="hljs-title function_">sucesscb</span>(<span class="hljs-string">'11111'</span>)
    },<span class="hljs-number">1000</span>)
}

<span class="hljs-comment">//回调地狱</span>
<span class="hljs-title function_">ajax</span>(<span class="hljs-string">'/aaa'</span>,<span class="hljs-function">(<span class="hljs-params">data</span>)=&gt;</span>{
    <span class="hljs-title function_">ajax</span>(<span class="hljs-string">'/bbb'</span>,<span class="hljs-function">(<span class="hljs-params">data</span>)=&gt;</span>{
        <span class="hljs-title function_">ajax</span>(<span class="hljs-string">'/ccc'</span>,<span class="hljs-function">(<span class="hljs-params">data</span>)=&gt;</span>{
	
        },<span class="hljs-function">()=&gt;</span>{

        })
    },<span class="hljs-function">()=&gt;</span>{

    })
},<span class="hljs-function">()=&gt;</span>{

})
</div></code></pre>
<p>如果处理函数的异步很多，就是异步1里面 有异步2…
就会形成很多嵌套 –&gt; 回调地狱，
不能try catch 捕获错误
不能return，影响美观不易于维护。
缺乏顺序性： 回调地狱导致的调试困难，和大脑的思维方式不符.
嵌套函数存在耦合性，一旦有所改动，就会牵一发而动全身，即（控制反转）
嵌套函数过多的多话，很难处理错误</p>
<h3 id="%E5%9B%9B%E3%80%81promise" tabindex="-1">四、promise</h3>
<p>解决回调地狱使用 ES6中的 <code>promise</code>，翻译过来就是**’承诺‘**,意思是在未来某一个时间点承诺返回数据给你。</p>
<ol>
<li>
<p><code>Promise</code>参数为一个回调函数，参数为resolve和reject</p>
<blockquote>
<p>resolve表示成功的回调</p>
<p>reject表示失败的回调</p>
</blockquote>
</li>
<li>
<p><code>Promise</code>有三种状态：pending / fulfilled/ rejected。</p>
</li>
</ol>
<blockquote>
<p>pending 就是未决的
fulfilled就是成功的
rejected可以理解为拒绝</p>
</blockquote>
<ol start="3">
<li>同时Promise有三种常用的方法：</li>
</ol>
<blockquote>
<p>then 表示异步成功执行后的数据状态为fulfilled；
catch 表示为异步失败后执行的数据状态rejected；
all 表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。</p>
</blockquote>
<ol start="4">
<li>使用Promise</li>
</ol>
<pre class="hljs"><code><div>
</div></code></pre>
<h4 id="%E6%A1%88%E4%BE%8B1%EF%BC%9A%E5%B0%81%E8%A3%85ajax%E6%A1%88%E4%BE%8B" tabindex="-1">案例1：封装ajax案例</h4>
<pre class="hljs"><code><div>  <span class="hljs-keyword">function</span> <span class="hljs-title function_">ajax</span>(<span class="hljs-params">url</span>){
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>)=&gt;</span>{
            <span class="hljs-keyword">let</span> xhr = <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLHttpRequest</span>()
            xhr.<span class="hljs-title function_">open</span>(<span class="hljs-string">'get'</span>, url)<span class="hljs-comment">//链接</span>
            xhr.<span class="hljs-title function_">send</span>()<span class="hljs-comment">//发送资源</span>
            xhr.<span class="hljs-property">onreadystatechange</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){
                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(xhr)
                <span class="hljs-keyword">if</span>(xhr.<span class="hljs-property">readyState</span> === <span class="hljs-number">4</span>){
                    <span class="hljs-keyword">if</span>(xhr.<span class="hljs-property">status</span> &gt;= <span class="hljs-number">200</span> &amp;&amp; xhr.<span class="hljs-property">status</span> &lt; <span class="hljs-number">300</span>){
                        xhr.<span class="hljs-property">responseText</span> <span class="hljs-comment">//json 字符串</span>
                        <span class="hljs-title function_">resolve</span>(res)
                    }<span class="hljs-keyword">else</span>{
                        <span class="hljs-title function_">reject</span>(xhr.<span class="hljs-property">responseText</span>)
                    }
                }
            }

        })

    }
    <span class="hljs-title function_">ajax</span>(<span class="hljs-string">'./01.json'</span>)
    .<span class="hljs-title function_">then</span>(<span class="hljs-function">(<span class="hljs-params">res</span>)=&gt;</span>{
        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res);

    })
    .<span class="hljs-title function_">catch</span>(<span class="hljs-function">(<span class="hljs-params">err</span>)=&gt;</span>{
        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(err);
    })
</div></code></pre>
<h4 id="%E6%A1%88%E4%BE%8B2%EF%BC%9Apromise%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8" tabindex="-1">案例2：promise链式调用</h4>
<p>什么是链式调用，也就是函数式编程</p>
<p>举例：</p>
<pre class="hljs"><code><div><span class="hljs-comment">//命令式编程：原生js开发或者jquery通过命令操作DOM对象完成数据更改，界面变化。</span>
<span class="hljs-comment">//声明式编程：框架底层已经封装号模块帮助我们来完成DoM的操作，只需去声明即可使用vuereactangular{{}</span>
<span class="hljs-comment">//编程范式：命令式编程和声明式编程</span>
<span class="hljs-comment">//编程范式：面向对象的编程与面向过程的编程</span>
<span class="hljs-comment">//面向过程的方式，他的第一个公民是函数，他围绕着函数进行编程，也就是函数式编程</span>
<span class="hljs-keyword">const</span> nums = [<span class="hljs-number">10</span>,<span class="hljs-number">20</span>,<span class="hljs-number">111</span>,<span class="hljs-number">222</span>,<span class="hljs-number">444</span>,<span class="hljs-number">40</span>,<span class="hljs-number">50</span>];

<span class="hljs-comment">//1、从nums数组中取出小于100的数</span>

<span class="hljs-keyword">let</span> newNums = []
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> n <span class="hljs-keyword">of</span> nums) {
    <span class="hljs-keyword">if</span> (n &lt; <span class="hljs-number">100</span>) {
        newNums.<span class="hljs-title function_">push</span>(n)
    }
}
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newNums);
<span class="hljs-comment">//2、从（1）要求中小于100的数都乘以2</span>


<span class="hljs-keyword">let</span> newNums2 = []
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> n <span class="hljs-keyword">of</span> newNums) {
    newNums2.<span class="hljs-title function_">push</span>(n * <span class="hljs-number">2</span>)
}
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newNums2);
<span class="hljs-comment">//3、从（2）要求中，把所有的数进行累加，得到最终结果</span>

<span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span> 
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> n <span class="hljs-keyword">of</span> newNums2) {
    total += n

}
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(total);

<span class="hljs-comment">//通过js逻辑操作完成需求</span>

<span class="hljs-comment">//函数式编程</span>
<span class="hljs-comment">//封装了一些函数用来实现一些效果</span>
<span class="hljs-comment">//1）filter函数的使用</span>
<span class="hljs-comment">//参数是一个回调函数，数组有多少个成员，就回调多少次</span>
<span class="hljs-keyword">let</span> newNums1 = nums.<span class="hljs-title function_">filter</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){ 
    <span class="hljs-comment">//回调函数编写过滤规则</span>
    <span class="hljs-comment">//匿名函数，有一个参数，每次回调数组成员，第一个n是10 第二个是20 以此类推</span>
    <span class="hljs-comment">//匿名函数被要求必须返回一个值，return，是布尔值 true 返回n进入数组,如果是flase就什么都不操作</span>
    <span class="hljs-keyword">return</span> n &lt; <span class="hljs-number">100</span>;

})

<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newNums1);

<span class="hljs-comment">// 2)map函数的使用</span>
<span class="hljs-comment">//它可以对数组中每个内容进行一些操作</span>
<span class="hljs-comment">//参数也为一个匿名的回调函数</span>
<span class="hljs-keyword">let</span> newnewNums = newNums1.<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">n</span>){
    <span class="hljs-comment">//参数指代每次回调的数组成员</span>
    <span class="hljs-keyword">return</span> n * <span class="hljs-number">2</span>
})

<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(newnewNums);

<span class="hljs-comment">//3)reduce函数，第一个参数为回调函数，第二个参数为开始的默认值</span>
<span class="hljs-comment">//作用就是对数组所有内容进行一个汇总</span>

<span class="hljs-keyword">let</span> total1 = newnewNums.<span class="hljs-title function_">reduce</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">preValue,n</span>){
    <span class="hljs-comment">//匿名函数中也有两个参数，第一个参数为preValue,值上一个返回的值</span>
    <span class="hljs-comment">//第二个参数为n,本次回调数组的成员</span>

    <span class="hljs-keyword">return</span> preValue + n
},<span class="hljs-number">0</span>)
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(total1);

<span class="hljs-comment">//链式编程</span>
<span class="hljs-comment">//把三个需求进行综合，一起提出</span>
<span class="hljs-keyword">let</span> totalnums = nums.<span class="hljs-title function_">filter</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">n</span>){
    <span class="hljs-keyword">return</span> n &lt; <span class="hljs-number">100</span>
}).<span class="hljs-title function_">mopd</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">n</span>){
    <span class="hljs-keyword">return</span> n * <span class="hljs-number">2</span>
}).<span class="hljs-title function_">reduce</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">preValue,n</span>){
    <span class="hljs-keyword">return</span> preValue + n
})
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(totalnums);



</div></code></pre>
<p>promise链式调用:</p>
<pre class="hljs"><code><div>&lt;!<span class="hljs-variable constant_">DOCTYPE</span> html&gt;
&lt;html lang="en"&gt;

&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;链式调用&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;script&gt;
        function ajax(url) {
            return new Promise((resolve, reject) =&gt; {
                let xhr = new XMLHttpRequest()
                xhr.open('get', url)//链接
                xhr.send()//发送资源
                xhr.onreadystatechange = function () {
                    console.log(xhr)
                    if (xhr.readyState === 4) {
                        if (xhr.status &gt;= 200 &amp;&amp; xhr.status &lt; 300) {
                            xhr.responseText //json 字符串
                            resolve(res)
                        } else {
                            reject(xhr.responseText)
                        }
                    }
                }

            })

        }
        ajax('./01.json')
            .then((res) =&gt; {
                console.log(res);
                return ajax('./02.json')
            })
            .then((res) =&gt; {
                console.log(res);
            })
            .catch((err) =&gt; {
                console.log(err);
            })
    &lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
</div></code></pre>
<h4 id="%E6%A1%88%E4%BE%8B3%EF%BC%9Apromise-all%E6%96%B9%E6%B3%95" tabindex="-1">案例3：promise all方法</h4>
<pre class="hljs"><code><div>
</div></code></pre>
<h4 id="%E6%A1%88%E4%BE%8B4%EF%BC%9Apromise-race%E6%96%B9%E6%B3%95" tabindex="-1">案例4：promise race方法</h4>
<pre class="hljs"><code><div>
</div></code></pre>
<p>优点：</p>
<p>Promise就是为了解决callback的问题而产生的。
Promise 实现了链式调用，也就是说每次 then 后返回的都是一个全新 Promise
如果我们在 then 中 return ，return 的结果会被 Promise.resolve() 包装
将回调函数的执行和结果比较清晰的分开了,解决了回调地狱的问题</p>
<p>缺点：</p>
<p>无法取消 Promise ，错误需要通过回调函数来捕获
一堆then，其实并没有将嵌套回调的问题根本上的解决，只是换了一种写法而已。</p>
<h3 id="%E4%BA%94%E3%80%81%E8%BF%87%E6%B8%A1%EF%BC%9Ayield%E6%96%B9%E6%A1%88-generator" tabindex="-1">五、过渡：yield方案 Generator</h3>
<p><strong>yield</strong>:Generator 函数是协程在 ES6 的实现，而yield是 Generator关键字， 异步操作需要暂停的地方，都用yield语句注明。</p>
<p><strong>Generator函数</strong>：是协程在 ES6 的实现，最大特点就是可以交出函数的执行权（即主动交出执行权，暂停执行）。
整个 Generator 函数就是一个封装的异步任务，或者说是异步任务的容器。异步操作需要暂停的地方，都用yield语句注明。</p>
<h3 id="%E5%85%AD%E3%80%81%E7%BB%88%E6%9E%81%E7%8E%A9%E6%B3%95%EF%BC%9Aes7-async%2Fawait" tabindex="-1">六、终极玩法：ES7 async/await</h3>
<p><code>async</code> 关键字用于修饰 <code>function</code>；
async函数的特征在于调用 <code>return</code>返回的并不是一个普通的值，而是一个 <code>promise</code>对象，如果正常 <code>return</code>了，则返回 <code>promise.resolve</code>(返回值)，如果 <code>throw</code>一个异常了，则返回 <code>promise.reject</code>(异常)
<code>await</code>关键字只能在 <code>async</code>函数中使用，不能在任意地方使用 <code>await</code>；
<code>await</code>关键字后跟一个 <code>promise</code>对象(就是想要执行的异步操作)，函数执行到 <code>await</code>后会退出该函数，直到事件轮询检查到 <code>promise</code>有了 <code>fulfilled</code>和 <code>rejected</code>状态，才重新执行这个函数后面的内容。</p>
<p><strong>async:</strong></p>
<pre class="hljs"><code><div>
</div></code></pre>
<p><strong>await:</strong></p>
<pre class="hljs"><code><div>
</div></code></pre>
<p>**优点：**async、await 是异步的终极解决方案
代码清晰，不用像 Promise 写一大堆 then 链，处理了回调地狱的问题
**缺点：**await 将异步代码改造成同步代码，如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。</p>

    </div>


</body></html>